home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Chip 1996 April
/
CHIP 1996 aprilis (CD06).zip
/
CHIP_CD06.ISO
/
hypertxt.arj
/
9311
/
VGAXGA.CD
< prev
next >
Wrap
Text File
|
1995-04-19
|
23KB
|
363 lines
@VA VGA, az XGA és a valós színû megjelenítôk@N
@Vlehetôségei@N
@VGrafikus konvertálások -- 5. rész@N
Sorozatunk befejezô részében a pillanatnyilag legfejlettebb
grafikus adapterek lehetôségeit fogjuk tárgyalni, különös
figyelmet szentelve az igen nagy felbontású/színhasználatú
üzemmódoknak, hiszen napjainkban ezek jelentik a PC szintû
képfeldolgozás csúcsát.
256 színû VGA üzemmódokban a köztes file leképzése majdnem
ugyanolyan elven történik, mint a 16 színû EGA/VGA
megjelenítések (CHIP, '93/4) esetén. Az egyik fontos
különbség az, hogy az átlagolandó mezô -- amit az éppen
kiértékelendô pixel körül olvasunk -- jóval kisebb lesz
kiterjedését tekintve, mint 16 szín esetén. Azért
csökkenthetjük az átlagolandó mezô méretét, mert 256 szín
esetén a kép elkészültekor feltehetôleg jóval kisebb
rasztermezôre volt szükség ahhoz, hogy ki lehessen keverni
a kívánt színt az adott felület számára (mivel a kívánthoz
jóval közelebbi színekbôl lehetett válogatni). Ez pedig
azt jelenti, hogy még egy kisebb leolvasott felület esetén
is igen nagy eséllyel helyes színt kapunk, ha kellô
alapossággal átlagoljuk a mátrixban található pontok
megfelelô színkomponenseit. Ha pedig nem kell túl nagy
mezôt olvasnunk, értelemszerûen jóval nagyobb esélyünk van
az élesség megôrzésére is.
Az eljárás során tehát egy adott pixel kiértékelésekor le
kell olvasnunk a kép környezô felületét -- legcélszerûbb
egy 3*3-as mátrixot letapogatni, amelynek a közepében van a
vizsgált pixel. Kinullázunk egy vörös, zöld és egy kék
átlagalapot, majd végigfutunk a mezô összes pixelén,
kiválasztva a pontok közül azokat, amelyeknek a
színeltérése a központi pixel mérvadónak tekintett színétôl
nem halad meg egy elôre definiált határértéket (ezekrôl a
pixelekrôl feltételezhetô ugyanis, hogy ugyanazt a
színfelületet próbálják meg kifejezni, mint a központi
pixel). A színeltérés számítása természetesen nem mást
jelent, mint hogy az aktuális pixel és a központi pixel
mindhárom színkomponensét egyenként kivonjuk egymásból (a
vöröset a vörösbôl, zöldet a zöldbôl, a kéket a kékbôl),
majd vesszük a különbségek abszolút értékeit, és a három
így kapott értéket összeadva megkapjuk az abszolút
színeltérést. Minél nagyobbra definiáljuk azt a határt,
amely meghatározza, hogy elfogadjuk-e az adott pixelt,
annál finomabban árnyalt képet kapunk majd, viszont
veszíthetünk az élességbôl. Kisebb tûréshatár esetén az
élesség kiváló lesz, de csökken az árnyalatgazdagság. Ha
kiválasztottuk azokat a pixeleket, amelyek a tûréshatár
alatti színeltéréssel rendelkeznek, akkor megfelelô
komponenseiket hozzáadjuk az azonos átlagalapokhoz (vörös,
zöld és kék), majd mindhárom átlagalapot elosztjuk az
elfogadott pixelek számával. A három átlagértéket
megfeleltetjük a vizsgált központi pixel vörös, zöld és kék
komponensének, majd felvesszük ôket a köztes file-ba.
32 ezer (pontosan 32|768) és 64 ezer (pontosan 65|536)
színû XGA megjelenítések esetén ugyanezt kell tennünk, csak
most jóval lejjebb szoríthatjuk a tûréshatárt a színek
nagyobb száma miatt -- megôrizve ezzel a kellô élességet.
Valós színû (true color) megjelenítések esetén
természetesen a kép megegyezik a róla leképzendô köztes
file-lal. A köztes file tulajdonképpen maga is egy valós
színû kép.
Egy apró trükkel elérhetjük, hogy a 256 színû
ábrázolásokról leképzôdô köztes file megtartsa kellô
élességét és mégis valamivel árnyalatgazdagabbá váljon --
anélkül, hogy növelnénk a tûréshatárt. A trükk lényege,
hogy a köztes file-on még egyszer elvégezzük ugyanezt a
mûveletsort, azzal a különbséggel, hogy a tûréshatárt jóval
lejjebb visszük (tehetjük, hiszen ez már majdnem megfelel
egy átlagos XGA képnek). Mindennek az ad értelmet, hogy az
elsô leképzéskor a program lehet, hogy elfogadott egy adott
ponthalmazt és átlagolta is ôket, de a pontok átlaga még
mindig nem adott kellô árnyaltságot, mert a 3*3-as
leolvasott mezô túl kicsi volt ahhoz, hogy benne a
megfelelô árnyalat kifejezôdhessen. A többszörös átlagolás
viszont tulajdonképpen ""kinyúl" az eredeti 3*3-as mezôbôl,
hiszen a vizsgált pont melletti pont már tartalmazza több
olyan pont átlagát is, amelyeket ô elérhetett a
letapogatáskor de a vizsgált pont nem. E trükknek persze
semmi értelme egy XGA kép esetén.
@VEgy kifinomult optimalizáció@N
A legutóbbi írásban (CHIP 93/04) már ismertettünk néhány
igen egyszerû és gyors, valamint néhány közepesen fejlett
optimalizálási algoritmust. Részletesen kifejtettük azt
is, hogy mit jelent a háromdimenziós, térbeli színkocka
elve. Az itt leírásra kerülô, igen jó minôségû
optimalizálási algoritmusok is ezt a színkockát fogják
használni a színek kiválasztásához.
Csak emlékeztetésképpen, az optimalizáció célja az, hogy a
rendelkezésre álló 262|144 színbôl (VGA) kiválaszthassuk
azt a 256-ot, amelynek segítségével leginkább ki tudjuk
fejezni a megjelenítendô kép árnyalatait. Az
optimalizációnak természetesen csak VGA üzemmódok esetén
van értelme, hiszen XGA és valós színû ábrázolások esetén
nincs paletta, amirôl válogatni lehetne (illetve van
paletta, de alapértelmezésben tartalmazza az összes
megjeleníthetô színt).
Elôször is, nullázzuk ki a színkocka összes elemét.
Fussunk végig az optimalizálandó képen, és minden egyes
pont leolvasásakor növeljük meg a térbeli színkockában
annak a térelemnek a számlálóját, ami elhelyezkedése
alapján az éppen leolvasott pixelszínt reprezentálja.
Ha ezzel elkészültünk, vágjuk fel a színkockát, ugyanazt az
elvet alkalmazva, amit korábbi írásunkban ismertettünk. Az
egyetlen különbség, hogy most nem 16 vagy 32 részre
szeleteljük fel, hanem 256 különálló térelemre. Tehetjük
azt is, hogy az elkészült elemeket máris elfogadjuk egy
palettaelem alapjául szolgáló térrészként, és súlyozott
átlagokat készítve belôlük létrehozzuk a palettát (lásd
késôbb), de így nem kapunk igazán jó eredményeket.
Elôfordulhat ugyanis, hogy a 256 térelem közül néhány
egyáltalán nem tartalmaz pixeleket, vagy csak kevés pixel
van bennük -- vagyis tulajdonképpen feleslegesen pazarolják
az értékes palettaelemeket. Ki kell válogatnunk tehát
azokat a térelemeket, amelyekre igaz az elôbbi kritérium.
Ehhez meg kell húznunk egy határt, amely azt határozza meg,
hogy minimum hány pixel tartalmazása esetén kell egy
térelemet elfogadhatónak tekinteni (azt, hogy egy térelem
hány pixelt tartalmaz, úgy számíthatjuk ki a
legegyszerûbben, hogy a bennük levô számlálók értékeit
összeadjuk). Eldöntjük, hogy ennek alapján hány térelem
minôsül feleslegesnek (X), és ki kell dobnunk az összes
felesleges térelemet. Ezután X-szer végre kell hajtanunk
azt, hogy rákeresünk a legtöbb pixelt tartalmazó térelemre,
félbevágjuk azt és újra kiértékeljük, hogy a félbevágott
részek hány pixelt tartalmaznak.
Ha minden jól megy, a végén ismét 256 érvényes térelemhez
jutunk. E térrészekben súlyozott átlagokat készítünk
(vagyis nullázunk egy vörös, zöld és kék átlagalapot;
végigfutunk a térrészben lévô összes színelem-számlálón, és
a színelem által reprezentált szín komponenseit annyiszor
adjuk hozzá az átlagalaphoz, amennyit a színelem számlálója
meghatároz; végül az átlagalapokat elosztjuk a térrész
által tartalmazott pixelek számával). Az elkészült 256
súlyozott színátlagot egyenként betöltjük a palettába, és
érvényesítjük a palettát.
A paletta elkészítésének másik lehetséges változata, hogy a
színkocka felszeletelésekor nem feltétlenül a leghosszabb
kiterjedés mentén vágunk, és nem feltétlenül félbe vágjuk
az adott térelemet, hanem úgy próbáljuk meg felszeletelni
azt, hogy a keletkezett részek a lehetô leginkább azonos
számú pixelt tartalmazzák -- esetleg kombinálhatjuk is
egymással a döntés elemeit, egyszerre figyelembe véve a
legnagyobb hosszúság szerinti vágás és az egyenlô eloszlás
elvét. Ha ilyesfajta elvet követünk, és így vágjuk végig
256 térelem ""mélységig" a kockát, akkor mellôzhetjük a
kiejtôs-újraszeletelôs algoritmust, hiszen minden kis
térrész viszonylag azonos ""értékû" lesz. Ilyenkor
egyszerûen elkészítjük a súlyozott színátlagokat, és
feltöltjük ôket az érvényesítendô palettába.
@VA köztes file-ok megjelenítése@N
A köztes file-okat VGA és XGA üzemmódokban raszterezve
jeleníthetjük meg, valós színû üzemmódban pedig
természetesen raszterezés nélkül, úgy, ahogy vannak. 256,
32/64 ezer színû raszterezéshez az elôzô írásban
ismertetett színes hibaszórásos rasztereljárás a
legmegfelelôbb, természetesen azzal a módosítással, hogy
VGA esetén a kapott szín alapján mûködô pixelkiválasztó
algoritmus nem 16, hanem 256 palettaelemet vizsgál végig a
legközelebbi színpont után kutatva. 32/64 ezer szín esetén
a legmegfelelôbb pixelérték kiválasztásához nem kell
végigkutatni a palettát, hanem egyszerûen el kell osztani
8/8/8-cal (32 ezer szín) illetve 8/4/8-cal (64 ezer szín) a
köztes file vörös/zöld/kék komponenseit, hiszen ez az
értékhármas eleve kijelöl egy pixelértéket az XGA palettán.
Igaz ugyan, hogy a legszebb eredményt a színes hibaszórásos
eljárás szolgáltatja, mégis érdemes egy további eljárást
szemügyre vennünk, mivel a hibaszórásnak bizony súlyos
hátrányai vannak. A legnagyobb visszásság az, hogy ha már
elkészítettünk egy képet, és késôbb X,Y pozícióban
módosítanunk kell azt valamilyen ok miatt, akkor
kénytelenek vagyunk az egészet újra rajzolni, hiszen nem
ismerjük az adott pozícióban a három színkomponens
vonatkozó hibaváltozóját. Szükségünk lehet egy olyan
eljárásra is, amely fix raszterezettséggel állítja elô a
képeket, olyasformán, mint ahogyan az a monokróm
merevrasztereknél történt.
Ållítsunk elô VGA-n egy általános, átfogó jellegû palettát.
A legcélszerûbb úgy eljárni, hogy a teljes vörös és a zöld
skálát 8-8, a kék skálát pedig négy részre osztva
elôállítjuk a skálaelemek összes kombinációját (8*8*4=256),
és megfeleltetjük az így kapott színeket a palettának. Ez
voltaképpen azt jelenti, hogy 3-3-2 bitet áldozunk a
vörös-zöld-kék skálákra a palettából: az aktuális
palettaelem 8 bites indexének felsô 3 bitje az adott szín
vörös értékét tartalmazza, a középsô 3 bit a zöld, míg az
alsó két bit a kék értéket jelenti (a kék színre a
legkevésbé érzékeny az emberi szem). XGA esetén a paletta
alapértelmezésben 8/8/8-as egységekben (32K szín) illetve
8/4/8-as egységekben (64K szín) tartalmazza a
vörös/zöld/kék komponenseket.
Az árnyalatok kellôen finom kikeveréséhez egyszerre
alkalmazzuk a monokróm konvertálásoknál is használt 8*8-as
merevrasztert, valamint a paletta színkomponensenkénti
osztottságát. A könnyebb megértés érdekében lássuk elôször
csak egy színkomponens teljes skálájának felépítését.
A vörös skála VGA esetén 8 részre van osztva, tehát 8 bites
teljesérték esetén 32 alatt tiszta fekete áll csak
rendelkezésünkre, 32 felett egy nagyon halvány tiszta
vörös, 64-tôl egy kicsit erôsebb vörös... és így tovább,
egészen a teljes vörös telítettségig. Raszterezést tehát
akkor kell végeznünk, ha már meghaladtunk egy olyan
színtelítettséget, ahol rendelkezésünkre állt egy tiszta
vörös palettaelem, de még nem értük el a következô vörös
palettaelemet. 0 és 32 között tehát raszterezni fogunk,
akárcsak 32 és 64 között, egészen 256-ig. Azt, hogy a 65
rendelkezésre álló merevraszter közül melyiket fogjuk
felhasználni, az attól függ, hogy milyen arányban osztjuk a
két rendelkezésre álló ""tiszta" vörös közötti skálát.
16-os telítettség esetén például az 50%-os telítettségû
rasztert (31) fogjuk használni, éppúgy, mint 48 esetén,
hiszen ezek a telítettségek pont félúton vannak a
szomszédos ""tiszta" palettaelemek közötti lyukban. Az
egyetlen különbség a monokróm raszterhasználathoz képest,
hogy most nem feketét rakunk akkor, ha nem találunk pontot
a rasztermezô megfelelô pontján, és nem fehéret akkor, ha
találunk; a fekete pont funkcióját itt a legközelebbi olyan
""tiszta" vörös szín veszi át, amely a pillanatnyi
telítettségtôl lefelé van a skálán, a fehérét pedig a
legközelebbi olyan ""tiszta" vörös, amely az aktuálisnál
feljebb helyezkedik el a telítettségek sorában.
Azt, hogy melyik pontot kell vizsgálnunk a 8*8-as
rasztermezôn belül, ugyanúgy kell eldöntenünk, mint a
monokróm képek esetén. Képlet szerint: Xrel = Xpos mod 8,
Yrel = Ypos mod 8 (ahol az Xrel;Yrel a rasztermezôn belüli
koordináták, az Xpos;Ypos az adott pontnak a kép bal felsô
sarkához viszonyított koordinátái, a mod pedig egy olyan
osztás, amely eredményként a mûvelet maradékát adja
vissza).
Egyszerû példával élve, 40-es vörös telítettség esetén, ha
a kirakandó pont koordinátái 37;113, akkor meg kell
vizsgálnunk a 25%-os telítettségû rasztert, azaz a 15-ös
indexû mátrixot, hogy tartalmaz-e pontot az 5;1-es
pozícióban (25% azért, mert a 40-es telítettség pont az 1/4
részénél osztja a 32 és a 64 közötti skálát, márpedig e két
""tiszta" vörös határolja a 40-es telítettséget). Ha nem
találunk pontot a raszter 5;1-es pozícióján, akkor a
37;113-as fizikai képpontra 32-es vörös telítettségû pixelt
rakunk ki, ha viszont találunk pontot az adott pozícióban,
akkor 64-es vörös árnyalatú pontot helyezünk el a kép
ugyanezen helyén.
A zöld és a kék skálák elkészítésének az elve ugyanez,
figyelembe véve persze a kék csatorna különbözô
osztottságát. Nekünk persze nem különálló skálákra van
szükségünk, hanem arra, hogy egy színkomponens-hármas
alapján a három raszterskála adott telítettségû helyeinek
tetszôleges kombinációját tudjuk megjeleníteni egy adott
ponton. Nincs azonban semmi probléma, hiszen a palettát úgy
építettük fel, hogy bármely három ""tiszta" szín bármely
tetszôleges kombinációja szerepel benne. Nincs hát más
dolgunk, mint hogy külön-külön a vörös, a zöld és a kék
komponensekre nézve elvégezzük az elôbbi mûveletsort,
megkapva az adott komponens-skálán megjelenítendô ""tiszta"
színt, majd megkeressük a palettának azt az elemét, amely
megegyezik az így megkapott ""tiszta" színkomponens-hármas
aktuális kombinációjával. Ez lesz az a pixel, amit
fizikailag megjelenítünk a képernyôn az adott X,Y
koordináták által meghatározott helyen.
Van azonban még egy apró probléma. Ha mondjuk 8 részre
osztjuk a teljes skálát, és 32-es egységenként lépünk egy
""tiszta" színt a telítettségi skálán, akkor a következô
színkomponens-erôsségi sorozatot kapjuk: 0, 32, 64, 96,
128, 160, 192, 224. Ezzel az a legnagyobb probléma, hogy a
legerôsebb komponens jóval alatta marad az elérhetô
maximális telítettségnek (ez a hiányosság különösen
érzékelhetô a kék skála esetében, ahol ugyanilyen elvet
követve a 192-es telítettség jelentené a legerôsebb
""tiszta" kék színt). Már az is éppen elég nagy baj, hogy
a megjelenô maximális fényességû pixelek is túl sötétek
lesznek. Az egészben leginkább az a katasztrofális, hogy a
megjelenítés során mi igenis kapunk olyan
komponens-értékeket, amelyek 224 illetve 192 felett vannak,
és ezekkel nem tudunk mit kezdeni, hiszen nem felelnek meg
egyik ""tiszta" színnek sem, viszont nincsenek két
""tiszta" szín között sem. A megoldás meglehetôsen
egyszerû; nem fix egységenként kell növelni a ""tiszta"
színek telítettségét, hanem egy egyszerû aránypárral kell
ôket rászámítani a 256-os skálára -- általános képlettel:
Telítettség = 255*(Aktuális / (Osztottság-1)). Ha tehát 8
részre osztunk egy skálát, akkor a telítettségi szintek 0
és 7 között lehetnek, s a maximális vörös telítettség =
255*(7/(8-1)), vagyis 255.
Természetesen ennek megfelelôen módosul az összes számszerû
adat, amit a magyarázathoz felhasználtunk, de az elv
ugyanaz marad. Ha mégsem akarjuk megváltoztatni az
elképzeléseinket (mármint a számszerû adatokat tekintve),
vagy úgy találjuk, hogy fix egységekkel dolgozva sokkal
egyszerûbb megírni az algoritmust, akkor tehetjük azt is,
hogy a bejövô adatokat arányosan rászámítjuk az
""egységenkénti" skála szerinti maximális komponens által
meghatározott értéktartományra (vörös és zöld esetén
0..224, kék esetén 0..192), de a palettaelemekbe fizikailag
akkor is az arányos számítással megkapott értékeket kell,
hogy töltsük (különben túl sötét lesz a megjelenô kép).
Az algoritmus ugyanígy mûködik 32 ezer illetve 64 ezer
színû megjelenítések során is, csupán a számszerû
konstansok változnak. Ha a 16 színû EGA és VGA üzemmódokat
nézzük, azokra is igaz, hogy a színes hibaszórás szebb
eredményeket produkál, mint ez a fajta osztott
merevraszteres tachnika -- viszont az elôbb leírtak igen
jól használhatók a 16 színû üzemmódokban is (8 színt
kihasználva, 2-2-2 részre bontva a színkomponenseket), és
az elônyei ott is érvényesülnek.
@VUtószó@N
Ezzel befejeztük a különbözô grafikus megjelenítôk közötti
képkonvertálások tárgyalását. A sorozatban nem volt célom
az, hogy az összes létezô megjelenítô kártya lehetôségeit
hardver- illetve programozási szinten ismertessem, csupán
egy átfogó, elvi képet akartam adni azokról a képkezelési
eljárásokról, amelyeket a fejlettebb grafikai programok
alkalmaznak, és amelyek segítségével a legelterjedtebb
grafikus adapterek grafikai lehetôségeit kihasználhatja
bárki, akinek ez célja, hobbija vagy érdeke. Az
ismertetett eljárásoknak rengeteg különbözô változata
létezik, és egymással is tetszôleges módon variálhatók.
Remélem, elegendô támpontot adtam ahhoz, hogy bárki, akit
érdekel a grafikus képfeldolgozás, és van hozzá némi
programozási gyakorlata, kellô hatékonysággal tudja
felhasználni ezeket az ismereteket, illetve
továbbfejlesztve azokat még jobb, még szebb, még
hatékonyabb képkezelési eljárásokat dolgozhasson ki.
@KNagy Gergely@N
@VReferencia@N
Grafikus konvertálások -- 1 (Monokróm 1): CHIP 93/január
Grafikus konvertálások -- 2 (Monokróm 2): CHIP 93/február
Grafikus konvertálások -- 3 (CGA, EGA 1): CHIP 93/április
Grafikus konvertálások -- 4 (CGA, EGA 2): CHIP 93/június